package tld.test.menu
{
	import flash.events.KeyboardEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;
	
	import tld.test.interpreter.runtime.Runtime;
	
	public class Console extends TextField
	{
		private var _point:uint;
		private var _runtime:Runtime;
		private var _lastResult:Object;
		
		public function Console(runtime:Runtime)
		{
			super();
			super.defaultTextFormat = 
				new TextFormat("_typewriter", 12, 0xED7B0B);
			super.background = true;
			super.backgroundColor = 0;
			super.addEventListener(
				KeyboardEvent.KEY_UP, this.keyHandler);
			super.type = TextFieldType.INPUT;
			super.multiline = true;
			this._runtime = runtime;
			this._runtime.setPrinter(this.print);
			super.text = "> ";
			this._point = 2;
		}
		
		public function submit():void
		{
			var buffer:String = super.text.substr(this._point);
			// TODO: save the lines into history
			var lines:Array = [];

			trace("console submits", buffer);
			this._lastResult = null;
			while (this._runtime.canRead(buffer))
			{
				buffer = this._runtime.run(buffer);
				this._lastResult = this._runtime.last();
				lines.push(this._lastResult);
				this._point = super.text.length - buffer.length;
			}
			this.print(this._lastResult);
		}
		
		public function run(command:String):Object
		{
			this._point = super.text.length;
			super.appendText(command);
			this.submit();
			return this._lastResult;
		}
		
		public function print(...rest):void
		{
			var text:String = "; " + rest.join("\n").replace("\n", "\n; ");
			var buffer:String = super.text.substr(this._point);
			
			super.replaceText(this._point, super.text.length, "");
			super.appendText(text + "\n> ");
			this._point += text.length + 3;
			super.appendText(buffer);
			super.scrollV = super.maxScrollV;
			super.setSelection(this._point, this._point);
		}
		
		private function keyHandler(event:KeyboardEvent):void
		{
			var buffer:String;
			var lines:Array;
			// TODO: we don't handle copy / paste here
			// That would require some more complex code
			switch (event.keyCode)
			{
				case Keyboard.ENTER:
					this.submit();
					break;
				case Keyboard.DELETE:
					if (this._point > 0) this._point--;
					break;
			}
		}
	}
}